/*
  Copyright (c) 2009, Krzysztof Langner

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package flexlint.model;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

import flexlint.as.parser.ASGrammar;
import flexlint.as.parser.ASTImportDeclaration;
import flexlint.as.parser.ParseException;
import flexlint.as.parser.SimpleNode;

/**
 * Represents action script project parsed AST
 * @author Krzysztof Langner
 */
public class FlexProject {
    
    // ---------------------------------------------------------------------------------------------
    /**
     * Initialize project from source on given path
     * @param path - Path to source
     */
    public FlexProject(String path){
        File        file = new File(path);
        
        if(file.getName().endsWith(".as")){
            parseASFile(file);
        }
        else{
            parseFolder(file);
        }
    }

    // ----------------------------------------------------------------------------------------------
    public Enumeration<ASPackage>   getPackages(){
        return packages.elements();
    }

    // ----------------------------------------------------------------------------------------------
    /**
     * @return number of packages
     */
    public int getPackageCount(){
        return packages.size();
    }
    
    // ----------------------------------------------------------------------------------------------
    private void parseFolder(File folder){
        File[]      files = folder.listFiles();
        
        for(int i = 0; i < files.length; i++){
            File file = files[i];
            
            if( !file.getName().startsWith(".") ){
                if(file.isDirectory() && !file.getName().startsWith(".")){
                    parseFolder(file);
                }
                else if(file.getName().endsWith(".as")){
                    parseASFile(file);
                }
            }
        }

    }

    // ----------------------------------------------------------------------------------------------
    private void parseASFile(File file){
        SimpleNode  node;
        
        try {
            FileInputStream fis = new FileInputStream(file);
            ASGrammar grammar = new ASGrammar(fis);
            // Look for exceptions
            node = grammar.parse();
            parseAST(node);
        } catch (IOException e) {
            logger.log(Level.WARNING, e.toString());
        } catch (ParseException e) {
            logger.log(Level.WARNING, e.toString());
        }
                    

    }

    // ----------------------------------------------------------------------------------------------
    private void parseAST(SimpleNode compilationUnit) {

    	ASPackage	pkg;
    	
    	pkg = addPackage((String)compilationUnit.jjtGetValue());
        // check children
        for (int i = 0; i < compilationUnit.jjtGetNumChildren(); ++i) {
            SimpleNode node = (SimpleNode)compilationUnit.jjtGetChild(i);
            if(node instanceof ASTImportDeclaration){
                pkg.addImport( (String)node.jjtGetValue() );
            }
        }    
    }

    // ----------------------------------------------------------------------------------------------
    /**
     * Add package with given name. If the name doesn't exist .
     */
    private ASPackage addPackage(String name) {

    	ASPackage	pkg;
    	
    	for (ASPackage p : packages){
            if(p.getName().compareTo(name) == 0){
            	return p;
            }
        }

    	pkg = new ASPackage(name);
        packages.add(pkg);
        
        return pkg;
    }


    // ----------------------------------------------------------------------------------------------
    // Private members
    /** Logger class */
    private static Logger logger = Logger.getLogger("FlexProject");

    /** Packages list */
    private Vector<ASPackage>   packages = new Vector<ASPackage>();
}
